package com.cqhz.quwan

import android.app.Application
import android.content.Context
import android.os.Handler
import android.os.Message
import android.support.multidex.MultiDex
import android.util.Log
import cn.jpush.android.api.JPushInterface
import com.amap.api.location.AMapLocationClient
import com.amap.api.location.AMapLocationClientOption
import com.amap.api.location.AMapLocationListener
import com.amap.api.location.AMapLocationQualityReport
import com.blankj.utilcode.util.Utils
import com.cqhz.quwan.common.KeyContract
import com.cqhz.quwan.model.HotLottery
import com.cqhz.quwan.model.LoginBean
import com.cqhz.quwan.service.API
import com.cqhz.quwan.util.*
import com.orhanobut.hawk.Hawk
import me.militch.quickcore.core.HasDaggerApplication
import me.militch.quickcore.core.impl.AppTarget
import me.militch.quickcore.di.component.AppComponent
import me.militch.quickcore.di.module.GlobalConfigModule
import me.militch.quickcore.di.module.HttpConfigModule
import me.militch.quickcore.repository.AutoInjectRepository


class APP : Application(), HasDaggerApplication<ActivityInject>, LoginSubscribe {

    companion object {
        const val MSG_SET_ALIAS = 0xFF
        const val MSG_SET_REMOVE_ALIAS = 0xFE
        var app: APP? = null
        fun get(): APP? = app
        var channel: String? = "EXH5"// 友盟渠道名

        var locationClient: AMapLocationClient? = null
        var locationOption: AMapLocationClientOption? = null
        var longitude: String? = ""
        var latitude: String? = ""
    }

    var loginInfo: LoginBean? = null
    val currentLottery = ArrayList<HotLottery>()
    val clog = CLogger(this::class.java)
    var sequence: Int = 0x99
    var isStart = false

    private val mHandler: Handler = object : Handler() {
        override fun handleMessage(msg: Message?) {
            super.handleMessage(msg)
            when (msg?.what) {
                MSG_SET_ALIAS -> {
                    // 调用 JPush 接口来设置别名。
                    JPushInterface.setAlias(applicationContext, 0xFF, msg.obj as String)
                }
                MSG_SET_REMOVE_ALIAS -> {
                    JPushInterface.deleteAlias(applicationContext, 0xFF)
                }
                else -> clog.i("Unhandled msg - ", msg?.what.toString())
            }
        }
    }

    override fun onCreate() {
        super.onCreate()
        app = this
        channel = getMetaDataVersion<String>(KeyContract.APP_CHANNEL) ?: "EXH5"

        // 获取定位
        initLocation()
        startLocation()

        // 初始化友盟统计
        UmengAnalyticsHelper.init(channel!!)
        Log.e("UmengAnalyticsHelper", channel)

        LoginObserver.register(this)
        Utils.init(this)
        JPushInterface.init(this)

        AppTarget.create(this)

//        Bugly.init(applicationContext, getMetaDataVersion(KeyContract.BUGLY_APPID), false)

        Hawk.init(applicationContext).build()
        loginInfo = Hawk.get<LoginBean>(KeyContract.LoginInfo)

        if (loginInfo != null) {
            setAlias(loginInfo?.phoneNumber)
        }
    }

    /****************************************定位 start****************************************/

    /**
     * 初始化定位信息
     */
    private fun initLocation() {
        // 初始化client
        locationClient = AMapLocationClient(this)
        locationOption = getDefaultOption()
        // 设置定位参数
        locationClient!!.setLocationOption(locationOption)
        // 设置定位监听
        locationClient!!.setLocationListener(locationListener)
    }

    /**
     * 开始定位
     *
     * @author Guojing
     * @since 2.8.0
     */
    private fun startLocation() {
        // 设置定位参数
        locationClient!!.setLocationOption(locationOption)
        // 启动定位
        locationClient!!.startLocation()
    }

    /**
     * 停止定位
     *
     * @author Guojing
     * @since 2.8.0
     */
    private fun stopLocation() {
        // 停止定位
        locationClient!!.stopLocation()
    }

    /**
     * 销毁定位
     *
     * @author Guojing
     * @since 2.8.0
     */
    private fun destroyLocation() {
        if (null != locationClient) {
            /**
             * 如果AMapLocationClient是在当前Activity实例化的，
             * 在Activity的onDestroy中一定要执行AMapLocationClient的onDestroy
             */
            locationClient!!.onDestroy()
            locationClient = null
            locationOption = null
        }
    }

    /**
     * 默认的定位参数
     *
     * @author Guojing
     * @since 2.8.0
     */
    private fun getDefaultOption(): AMapLocationClientOption {
        val mOption = AMapLocationClientOption()
        mOption.locationMode = AMapLocationClientOption.AMapLocationMode.Hight_Accuracy//可选，设置定位模式，可选的模式有高精度、仅设备、仅网络。默认为高精度模式
        mOption.isGpsFirst = false//可选，设置是否gps优先，只在高精度模式下有效。默认关闭
        mOption.httpTimeOut = 30000//可选，设置网络请求超时时间。默认为30秒。在仅设备模式下无效
        mOption.interval = 2000//可选，设置定位间隔。默认为2秒
        mOption.isNeedAddress = true//可选，设置是否返回逆地理地址信息。默认是true
        mOption.isOnceLocation = true//可选，设置是否单次定位。默认是false
        mOption.isOnceLocationLatest = true//可选，设置是否等待wifi刷新，默认为false.如果设置为true,会自动变为单次定位，持续定位时不要使用
        AMapLocationClientOption.setLocationProtocol(AMapLocationClientOption.AMapLocationProtocol.HTTP)//可选， 设置网络请求的协议。可选HTTP或者HTTPS。默认为HTTP
        mOption.isSensorEnable = false//可选，设置是否使用传感器。默认是false
        mOption.isWifiScan = true //可选，设置是否开启wifi扫描。默认为true，如果设置为false会同时停止主动刷新，停止以后完全依赖于系统刷新，定位位置可能存在误差
        mOption.isLocationCacheEnable = true //可选，设置是否使用缓存定位，默认为true
        mOption.geoLanguage = AMapLocationClientOption.GeoLanguage.DEFAULT//可选，设置逆地理信息的语言，默认值为默认语言（根据所在地区选择语言）
        return mOption
    }

    /**
     * 获取GPS状态的字符串
     *
     * @param statusCode GPS状态码
     * @return
     */
    private fun getGPSStatusString(statusCode: Int): String {
        var str = ""
        when (statusCode) {
            AMapLocationQualityReport.GPS_STATUS_OK -> str = "GPS状态正常"
            AMapLocationQualityReport.GPS_STATUS_NOGPSPROVIDER -> str = "手机中没有GPS Provider，无法进行GPS定位"
            AMapLocationQualityReport.GPS_STATUS_OFF -> str = "GPS关闭，建议开启GPS，提高定位质量"
            AMapLocationQualityReport.GPS_STATUS_MODE_SAVING -> str = "选择的定位模式中不包含GPS定位，建议选择包含GPS定位的模式，提高定位质量"
            AMapLocationQualityReport.GPS_STATUS_NOGPSPERMISSION -> str = "没有GPS定位权限，建议开启gps定位权限"
        }
        return str
    }

    /**
     * 定位监听
     */
    private var locationListener: AMapLocationListener = AMapLocationListener { location ->
        if (null != location) {

            val sb = StringBuffer()
            // errCode等于0代表定位成功，其他的为定位失败，具体的可以参照官网定位错误码说明
            if (location.errorCode == 0) {
                longitude = location.longitude.toString()
                latitude = location.latitude.toString()


                sb.append("定位成功" + "\n")
                sb.append("定位类型: " + location.locationType + "\n")
                sb.append("经    度    : " + location.longitude + "\n")
                sb.append("纬    度    : " + location.latitude + "\n")
                sb.append("精    度    : " + location.accuracy + "米" + "\n")
                sb.append("提供者    : " + location.provider + "\n")

                sb.append("速    度    : " + location.speed + "米/秒" + "\n")
                sb.append("角    度    : " + location.bearing + "\n")
                // 获取当前提供定位服务的卫星个数
                sb.append("星    数    : " + location.satellites + "\n")
                sb.append("国    家    : " + location.country + "\n")
                sb.append("省            : " + location.province + "\n")
                sb.append("市            : " + location.city + "\n")
                sb.append("城市编码 : " + location.cityCode + "\n")
                sb.append("区            : " + location.district + "\n")
                sb.append("区域 码   : " + location.adCode + "\n")
                sb.append("地    址    : " + location.address + "\n")
                sb.append("兴趣点    : " + location.poiName + "\n")
            } else {
                //定位失败
                sb.append("定位失败" + "\n")
                sb.append("错误码:" + location.errorCode + "\n")
                sb.append("错误信息:" + location.errorInfo + "\n")
                sb.append("错误描述:" + location.locationDetail + "\n")
            }
            sb.append("***定位质量报告***").append("\n")
            sb.append("* WIFI开关：").append(if (location.locationQualityReport.isWifiAble) "开启" else "关闭").append("\n")
            sb.append("* GPS状态：").append(getGPSStatusString(location.locationQualityReport.gpsStatus)).append("\n")
            sb.append("* GPS星数：").append(location.locationQualityReport.gpsSatellites).append("\n")
            sb.append("* 网络类型：" + location.locationQualityReport.networkType).append("\n")
            sb.append("* 网络耗时：" + location.locationQualityReport.netUseTime).append("\n")
            sb.append("****************").append("\n")

            // 解析定位结果，
            val result = sb.toString()
            Log.e("Location", result)
        } else {
            Log.e("Location", "定位失败，loc is null")
        }
    }

    override fun onLowMemory() {
        stopLocation()
        super.onLowMemory()
    }

    override fun onTerminate() {
        destroyLocation()
        super.onTerminate()
    }

    /****************************************定位 end****************************************/

    override fun login(loginBean: LoginBean?) {
        this.loginInfo = loginBean
        if (loginInfo != null) {
            setAlias(loginInfo?.phoneNumber)
        } else {

        }
    }

    private fun setAlias(phoneNumber: String?) {
        // 调用 Handler 来异步设置别名
        if (phoneNumber != null) {
            mHandler.sendMessage(mHandler.obtainMessage(MSG_SET_ALIAS, phoneNumber))
        }
    }

    fun getMobileBrand(): String {
        return android.os.Build.BRAND
    }

    fun getMobileModel(): String {
        return android.os.Build.MODEL
    }

    fun getIMEI(): String {
        return APPUtil.getPhoneIMEI()
    }

    private fun removeAlias() {

    }

    override fun attachBaseContext(base: Context?) {
        super.attachBaseContext(base)
        MultiDex.install(this)
    }

    override fun setupGlobalConfigModule(): GlobalConfigModule {
        return GlobalConfigModule.builder(this)
                .setRepositoryStoreHelper(AutoInjectRepository())
                .build()
    }

    override fun setupHttpConfigModule(): HttpConfigModule {
        return HttpConfigModule.builder()
                .setHost(API.HOST)
                .setInterceptor(GlobalRequestInterceptor())
                .build()
    }

    override fun activityComponent(appComponent: AppComponent?): ActivityInject? {
        return DaggerActivityInject.builder().appComponent(appComponent).build()
    }
}